#include "disk_io.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

// 我们可以简化头文件包含，只保留必要的
#ifdef _WIN32
// 移除不需要的Windows头文件
#endif

// 生成页面文件路径
// 参数：
//   data_dir - 数据目录路径
//   page_id - 页面ID
// 返回值：
//   成功返回页面文件路径字符串（需手动释放），失败返回NULL
char* disk_get_page_filename(const char* data_dir, page_id_t page_id) {
    char* filename = malloc(256);
    if (!filename) {
        return NULL;
    }

    // 改进：确保路径拼接正确处理各种情况
    #ifdef _WIN32
    snprintf(filename, 256, "%s\\page_%u.dat", data_dir, page_id);
    #else
    snprintf(filename, 256, "%s/page_%u.dat", data_dir, page_id);
    #endif
    return filename;
}

// 从磁盘加载页面
// 参数：
//   data_dir - 数据目录路径
//   page_id - 页面ID
//   buffer - 接收页面数据的缓冲区（至少PAGE_SIZE字节）
// 返回值：
//   STORAGE_OK表示成功，其他值表示失败类型
storage_error_t disk_load_page(const char* data_dir, page_id_t page_id, uint8_t* buffer) {
    char* filename = disk_get_page_filename(data_dir, page_id);
    if (!filename) {
        return STORAGE_ERROR_MEMORY;
    }

    FILE* file = fopen(filename, "rb");
    free(filename);

    if (!file) {
        // 文件不存在，应该返回错误而不是创建空页面
        return STORAGE_ERROR_NOT_FOUND;
    }

    size_t bytes_read = fread(buffer, 1, PAGE_SIZE, file);
    fclose(file);

    if (bytes_read != PAGE_SIZE) {
        return STORAGE_ERROR_IO;
    }

    return STORAGE_OK;
}

// 保存页面到磁盘 - 简化版
storage_error_t disk_save_page(const char* data_dir, page_id_t page_id, const uint8_t* data) {
    // 增强错误检查
    if (!data_dir || !data) {
        fprintf(stderr, "ERROR: disk_save_page: NULL input parameters\n");
        return STORAGE_ERROR_INVALID;
    }

    // 为文件名分配足够的空间
    char filename[512]; // 使用栈上的固定大小缓冲区，避免动态分配
    
    #ifdef _WIN32
    snprintf(filename, sizeof(filename), "%s\\page_%u.dat", data_dir, page_id);
    #else
    snprintf(filename, sizeof(filename), "%s/page_%u.dat", data_dir, page_id);
    #endif

    FILE* file = fopen(filename, "wb");
    if (!file) {
        fprintf(stderr, "ERROR: disk_save_page: Failed to open file %s - %s\n", filename, strerror(errno));
        return STORAGE_ERROR_IO;
    }
    
    // 分块写入数据，避免单次大数据写入可能的问题
    size_t total_written = 0;
    const size_t chunk_size = 1024; // 1KB的块大小
    while (total_written < PAGE_SIZE) {
        size_t to_write = (PAGE_SIZE - total_written) > chunk_size ? chunk_size : (PAGE_SIZE - total_written);
        size_t written = fwrite(data + total_written, 1, to_write, file);
        if (written != to_write) {
            fprintf(stderr, "ERROR: disk_save_page: Partial write - wrote %zu bytes, expected %zu\n", written, to_write);
            fclose(file);
            return STORAGE_ERROR_IO;
        }
        total_written += written;
    }
    
    // 确保数据刷新到磁盘
    if (fflush(file) != 0) {
        fprintf(stderr, "ERROR: disk_save_page: fflush failed - %s\n", strerror(errno));
        fclose(file);
        return STORAGE_ERROR_IO;
    }

    // 安全关闭文件
    if (fclose(file) != 0) {
        fprintf(stderr, "ERROR: disk_save_page: fclose failed - %s\n", strerror(errno));
        return STORAGE_ERROR_IO;
    }

    return STORAGE_OK;
}
// 从磁盘删除页面
storage_error_t disk_delete_page(const char* data_dir, page_id_t page_id) {
    char* filename = disk_get_page_filename(data_dir, page_id);
    if (!filename) {
        return STORAGE_ERROR_MEMORY;
    }

    int result = remove(filename);
    free(filename);

    return (result == 0) ? STORAGE_OK : STORAGE_ERROR_IO;
}